<?php
/** 
 * @Author: Bryant  
 * @Date: 2023-06-12 14:37:58 
 * @method post 
 * @title 生成邀请码 
 */

namespace app\common\model;


class Invite
{
    const BASE_PLAYER_ID = 10000000;
    const START_PLAYER_ID = 1000000100;

    const NPC_ID = 100000001;
    const NPC_USER_ID = 'BAQAAB';
    const NPC_SUSER_ID = 'FZOFCFGUEOHFSIUDIMIPLIZ';
    const NPC_DEVICE_ID = 'NPC001';


    public static function getLetters($num, $letters = array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"), $base = 25)
    {
        $remainder = $num % $base;
        $quotient = intval($num / $base);
        if ($quotient == 1) {
            return $letters[$quotient] . $letters[$remainder];
        } else if ($quotient < 1) {
            return $letters[$remainder];
        } else {
            return self::getLetters($quotient, $letters, $base) . $letters[$remainder];
        }
    }

    public static function getNum($string, $letters = array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"), $base = 26)
    {
        $val = 0;
        $len = strlen($string);
        for ($i = 0; $i < $len; $i++) {
            $l = substr($string, $i, 1);
            $num = array_search($l, $letters);
            $val += pow($base, $len - 1 - $i) * $num;
        }
        return $val;
    }

    public static function crc32FarmId($farmid)
    {
        $crcV = sprintf("%u", crc32($farmid));
        $int = intval($crcV) + self::BASE_PLAYER_ID;
        return strtolower(self::getLetters($int));
    }

    public static function rightOneLetter($low_farmid)
    {
        $rt = array();
        foreach ($low_farmid as $letter) {
            if ($letter == 'z')
                $rt[] = 'a';
            else {
                $rt[] = chr(ord($letter) + 1);
            }
        }
        return $rt;
    }

    public static function leftOneLetter($low_farmid)
    {
        $rt = array();
        foreach ($low_farmid as $letter) {
            if ($letter == 'a')
                $rt[] = 'z';
            else {
                $rt[] = chr(ord($letter) - 1);
            }
        }
        return $rt;
    }

    public static function insertFarmid($farmid)
    {
        $rt = array();
        for ($i = 0; $i < 16; $i++) {
            $rt[] = chr(mt_rand(97, 122));
        }
        $start_index = mt_rand(1, 15);
        $rt[0] = chr(96 + $start_index);
        $step_index = 0;
        foreach ($farmid as $key => $value) {
            if ($key % 2 == 0) {
                $step_index += 1;
            } else {
                $step_index += 2;
            }
            $index = ($start_index + $step_index) % 15 + 1;
            $rt[$index] = $value;
        }
        return $rt;
    }

    public static function extractFarmid($snsid)
    {
        $rt = array();

        $start_index = intval(ord($snsid[0]) - 96);
        $step_index = 0;
        for ($key = 0; $key < 7; $key++) {
            if ($key % 2 == 0) {
                $step_index += 1;
            } else {
                $step_index += 2;
            }
            $index = ($start_index + $step_index) % 15 + 1;
            $rt[] = $snsid[$index];
        }
        return $rt;
        //return implode($rt);
    }

    public static function encryptFarmId($farmid)
    {
        if (strlen($farmid) == 7) {
            $low_farmid = strtolower($farmid);
            $low_farmid = str_split($low_farmid);
            $tmp_farmid = self::rightOneLetter($low_farmid);
            $snsid16 = implode(self::insertFarmid($tmp_farmid));
            $crc = self::crc32FarmId($farmid);
            $snsid = $snsid16 . $crc;
            return strtoupper($snsid);
        }
        return false;
    }

    public static function decryptFarmId($snsid)
    {
        $snsid = strtolower($snsid);
        if (strlen($snsid) == 23) {
            $snsid = substr($snsid, 0, -7);
            $low_farmid = self::extractFarmid($snsid);
            $low_farmid = implode(self::leftOneLetter($low_farmid));
            $farmid = strtoupper($low_farmid);
            return $farmid;
        }
        return false;
    }

    public static function getUserIdBySuserId($suser_id)
    {
        return self::decryptFarmId($suser_id);
    }

    public static function getSuserIdByUserId($user_id)
    {
        return self::encryptFarmId($user_id);
    }

    public static function getPlayerIdBySuserId($suser_id)
    {
        return self::getNum(self::decryptFarmId($suser_id));
    }

    public static function getUserId($player_id)
    {
        $player_id += self::BASE_PLAYER_ID;
        return self::getLetters($player_id);
    }

    public static function getPlayerId($user_id)
    {
        return self::getNum($user_id);
    }

    public static function getSuserId($player_id)
    {
        return self::encryptFarmId(self::getLetters($player_id));
    }
}
